﻿using System;
using System.Reactive.Subjects;

namespace Property.Reloaders
{
    public partial class StateFilterReloaderDecoratorPrototype<T, TState>
    {
        private class DecoratorInstance : ReloaderDecorator<T>, IReloader
        {
            public DecoratorInstance(IReloaderPrototype<T> compositionBasePrototype,
                Func<T> getValue, Action<T> applyValue, Action<bool> applyStatus,
                Func<TState, TState> getFilterState, Func<IObservable<TState>, IObservable<TState>> filter)
                : base(compositionBasePrototype, getValue, applyValue, applyStatus)
            {
                if (getFilterState == null) throw new ArgumentNullException("getFilterState");
                if (filter == null) throw new ArgumentNullException("filter");

                _GetFilterState = getFilterState;
                _InputRhythm = new Subject<TState>();
                _ActionSubscription = filter(_InputRhythm).Subscribe(_ => _CompositionBase.Go());
            }

            //=//

            private readonly ISubject<TState> _InputRhythm;
            private readonly IDisposable _ActionSubscription;

            private readonly Func<TState, TState> _GetFilterState;
            private TState FilterState;

            public override void Go()
            {
                var prevFilterState = FilterState;
                FilterState = _GetFilterState(FilterState);
                _InputRhythm.OnNext(prevFilterState);
            }

            public override void Dispose()
            {
                _ActionSubscription.Dispose();
                base.Dispose();
            }
        }
    }
}
